﻿using System;
using System.Collections.Generic;

namespace EnterpriseFramework.DataAccess
{
    public class DicCache<T>
    {
        private int size = 0;
        private Dictionary<string, LinkedListNode<T>> dict;
        private LinkedList<T> list;

        public DicCache(int size)
        {
            this.size = size < 5 ? 5 : size;
            dict = new Dictionary<string, LinkedListNode<T>>(this.size, StringComparer.Ordinal);
            list = new LinkedList<T>();
        }

        /// <summary>
        /// Stores the given object. Overwrites if key exists.
        /// </summary>
        /// <param name="key">key under which to store given object</param>
        /// <param name="item">object to store</param>
        public void Put(string key, T item)
        {
            LinkedListNode<T> node;
            if (dict.TryGetValue(key, out node))
            {
                list.Remove(node);
                node = new LinkedListNode<T>(item);
                dict[key] = node;
                list.AddFirst(node);
            }
            else
            {
                if (list.Count == size)
                    list.RemoveLast();
                node = new LinkedListNode<T>(item);
                dict[key] = node;
                list.AddFirst(node);
            }
        }

        /// <summary>
        /// Returns an object associated with given key.
        /// </summary>
        /// <param name="key">key under which an object was previously stored</param>
        /// <returns>object or null if key is not found</returns>
        public T Get(string key)
        {
            LinkedListNode<T> node;
            if (dict.TryGetValue(key, out node))
            {
                list.Remove(node);
                list.AddFirst(node);
                return node.Value;
            }
            return default(T);
        }
    }
}
